package com.swak.netty.tcp;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import com.swak.Constants;
import com.swak.OS;
import com.swak.exception.RemotingException;
import com.swak.reactivex.p2p.PeerID;
import com.swak.reactivex.threads.Contexts;
import com.swak.reactivex.transport.Channel;
import com.swak.reactivex.transport.ExchangeClient;
import com.swak.reactivex.transport.ExchangeHandlerAdapter;
import com.swak.reactivex.transport.Exchangers;
import com.swak.reactivex.transport.Message;
import com.swak.reactivex.transport.TransportMode;
import com.swak.reactivex.transport.resources.LoopResources;
import com.swak.registry.URL;
import com.swak.utils.JsonMapper;
import com.swak.utils.Maps;

/**
 * 这是一款比较通用的基于  TCP 的通信服务
 * 
 * @author 618lf
 */
@SuppressWarnings("deprecation")
public class Client extends ExchangeHandlerAdapter {

	private LoopResources resources = Contexts.createEventLoopResources(TransportMode.OS, 1, 2, "Test.EventLoop-",
			false, 2, TimeUnit.SECONDS);

	ExchangeClient client;
	URL url;

	public Client() throws RemotingException {
		Map<String, String> parameters = Maps.newHashMap();
		parameters.put(Constants.Bind_Host, Constants.ANYHOST);
		parameters.put(Constants.Heartbeat, String.valueOf(Constants.Default_Heartbeat));
		this.url = new URL("Test", OS.ip(), 10889, parameters);
		this.client = Exchangers.connect(url, resources, this);
	}

	/**
	 * 仅仅是收到数据，对于发送的请求，不会执行此
	 */
	@Override
	public void received(Channel channel, Object message) throws RemotingException {
		System.out.println("仅仅是收到数据： " + JsonMapper.toJson(message));
	}

	public void sent(String message) throws RemotingException {
		this.client.send(Message.forMessage().setData(message));
	}

	public CompletableFuture<Object> request(String message) throws RemotingException {
		return this.client.request(Message.forRequest().addOption(Message.TwoWay).setData(message));
	}

	@Override
	public void caught(Channel channel, Throwable exception) throws RemotingException {
		super.caught(channel, exception);
		System.out.println("触发异常");
	}

	public static void main(String[] args) throws RemotingException, InterruptedException, ExecutionException {
		Client client = new Client();
		System.out.println("推送数据:");

		Map<String, String> parameters = Maps.newHashMap();
		parameters.put(Constants.Bind_Host, Constants.ANYHOST);
		parameters.put(Constants.Heartbeat, String.valueOf(Constants.Default_Heartbeat));
		parameters.put(Constants.Host_Name, OS.hostName());
		parameters.put(Constants.Peer_Id, "a1bcddcd-a2e1-401a-8e62-8098189760ef");
		URL peerURL = new URL("Riad", OS.ip(), OS.randomAvailablePort(), parameters);
		PeerID PeerID2 = PeerID.remotePeerID(peerURL);

		// 写并不会触发异常，如果监听写结果，则会等待写的异常产生，从而抛出异常；
		// client.client.send(Message.forMessage().setData(PeerID2));
		// 等待写入结果会
		client.client.send(Message.forMessage().setData(PeerID2), true);
		// 得到异常会触发
		// CompletableFuture<Object> future =
		// client.client.request(Message.forRequest().setData(PeerID2));
		// future.get();
	}
}
